package com.ynet.middleground.office.utils;

import com.google.common.base.Throwables;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.ynet.core.log.IfpLogger;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;

/**
 * 文件处理工具类
 * @author yang
 */
public class FileUtils {

    /**
     * 根据url文件和目标路径,生成本地文件
     * @param url 远程url地址
     * @param fullLocalFilePath 本地存储路径包含文件名
     */
    public static void downloadFileFromUrl(String url, String fullLocalFilePath) {
        InputStream inputStream = null;
        try {
            URL imageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection();
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            inputStream = conn.getInputStream();
        } catch (IOException e) {
            throw new RuntimeException("文件读取时时发生异常", e);
        }

        try (FileOutputStream outputStream = new FileOutputStream(fullLocalFilePath);
             ReadableByteChannel inputChannel = Channels.newChannel(inputStream);
             WritableByteChannel outputChannel = Channels.newChannel(outputStream)) {

            ByteBuffer buffer = ByteBuffer.allocate(1048576);

            while (inputChannel.read(buffer) >= 0) {
                buffer.flip();
                outputChannel.write(buffer);
                buffer.clear();
            }
        } catch (Exception ex) {
            throw new RuntimeException("写入输出流时发生异常", ex);
        }
    }

    /**
     * Word to Pdf
     * @param source 本地Word源路径
     * @param target 生成目标pdf文件路径
     */
    public static void word2Pdf(String source, String target) {
        long start = System.currentTimeMillis();
        ActiveXComponent app = null;
        Dispatch doc = null;
        try {
            File targetFile = new File(target);
            if (targetFile.exists()) {
                targetFile.delete();
            }

            ComThread.InitSTA();
            app = new ActiveXComponent("Word.Application");
            app.setProperty("Visible", false);
            Dispatch docs = app.getProperty("Documents").toDispatch();

            IfpLogger.info("office", "打开文档:{}", source);
            doc = Dispatch.call(docs, "Open", source, false, true).toDispatch();

            IfpLogger.info("office", "转换文档到PDF:{}", target);
            // wordSaveAsPDF为特定值17
            Dispatch.call(doc, "SaveAs", target, 17);

            long end = System.currentTimeMillis();
            IfpLogger.info("office", "转换完成用时：:{}", (end - start) + "ms.");
        } catch (Exception e) {
            IfpLogger.error("office", "Word转换pdf失败, source:{}, exception:{}", source, Throwables.getStackTraceAsString(e));
            e.printStackTrace();
        } finally {
            if (doc != null) {
                Dispatch.call(doc, "Close", false);
            }
            if (app != null) {
                // 不保存待定的更改
                app.invoke("Quit", 0);
            }
            ComThread.Release();
        }
    }

}
